package com.example.bluetooth.ble.manager;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Message;
import android.util.Log;

import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.example.bluetooth.ble.listener.OnConnectListener;
import com.example.bluetooth.ble.listener.OnDisconnectListener;
import com.example.bluetooth.ble.listener.OnWriteServiceListener;
import com.example.bluetooth.ble.service.BluetoothLeService;
import com.example.bluetooth.ble.utils.BluetoothControlUtil;
import com.example.bluetooth.ble.utils.DataProcessUtil;


/**
 * Created by HP on 2017/5/24.
 */

public class BluetoothControl {
    private static final String TAG = "BluetoothControl";

    public static final String CURRENT_ADDRESS = "current_address";
    public static final int READ_RESULT = 110;//发送数据返回结果
    public static final int CONFIRM_RESULT = 111;//发送数据返回结果

    private OnConnectListener mOnConnectListener;
    private OnDisconnectListener mOnDisconnectListener;
    private OnWriteServiceListener mOnWriteServiceListener;

    public void setOnConnectListener(OnConnectListener onConnectListener) {
        mOnConnectListener = onConnectListener;
    }

    public void setOnDisconnectListener(OnDisconnectListener onDisconnectListener) {
        mOnDisconnectListener = onDisconnectListener;
    }

    public void setOnWriteServiceListener(OnWriteServiceListener onWriteServiceListener) {
        mOnWriteServiceListener = onWriteServiceListener;
    }

    private DataProcessUtil mDataProcessUtil;
    private BluetoothControlUtil mBluetoothControlUtil;

    public BluetoothControl() {
        mDataProcessUtil = DataProcessUtil.getInstance();
        mBluetoothControlUtil = BluetoothControlUtil.getInstance();
    }

    /**
     * 注册广播
     * 注册一次就行了，一般在主界面注册，注册两次会有两次处理结果
     *
     * @param context
     */
    public void registerLocalBroadcast(Context context) {
        LocalBroadcastManager.getInstance(context).registerReceiver(localBroadcastReceiver, getLocalIntentFilter());
    }

    private static IntentFilter getLocalIntentFilter() {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(BluetoothLeService.START_WRITE_SERVER);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
        return intentFilter;
    }

    /**
     * 蓝牙操作返回数据处理
     */
    private BroadcastReceiver localBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(BluetoothLeService.ACTION_GATT_CONNECTED)) {
                BluetoothControlUtil.getInstance().setCurrentAddress(intent.getStringExtra(CURRENT_ADDRESS));
                if (mOnConnectListener != null)
                    mOnConnectListener.onConnect(intent.getStringExtra(CURRENT_ADDRESS));
            } else if (action.equals(BluetoothLeService.ACTION_GATT_DISCONNECTED)) {
                Log.e(TAG, "onReceive: 失去连接");
                if (mOnDisconnectListener != null)
                    mOnDisconnectListener.onDisconnect();
            } else if (action.equals(BluetoothLeService.START_WRITE_SERVER)) {
                Log.e(TAG, "onReceive: 建立连接");
                if (mOnWriteServiceListener != null)
                    mOnWriteServiceListener.onWriteService();
            } else if (action.equals(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED)) {
                BluetoothLeService.getInstance().enableTXNotification();
            } else if (action.equals(BluetoothLeService.ACTION_DATA_AVAILABLE)) {
                final byte[] txValue = intent.getByteArrayExtra(BluetoothLeService.EXTRA_DATA);
                Log.e(TAG, "onReceive: " + mDataProcessUtil.bytes2HexString(txValue));
                if (txValue[0] == (byte) 0x4B) {
                    //判断反向帧
                    byte[] fx = new byte[1];
                    fx[0] = (byte) (txValue[1] & 0x20);
                    if (fx[0] == (byte) 0x20) {
                        byte end = (byte) (txValue[1] & 0x40);
                        boolean endState = false;
                        if (end == (byte) 0x40) {
                            endState = true;
                        }
                        //判断返回是否正确
                        byte[] st = new byte[1];
                        st[0] = (byte) (txValue[1] & 0x10);
                        if (st[0] == (byte) 0x00) {
                            if (null != mOnSendResultListener)
                                mOnSendResultListener.result(true, endState);
                        } else if (st[0] == (byte) 0x10) {
                            if (null != mOnSendResultListener)
                                mOnSendResultListener.result(false, endState);
                        }
                    }
                }
                if (txValue[0] == (byte) 0x4A) {
                    byte[] value = new byte[]{(byte) 0x4B, (byte) (txValue[1] & (byte) 0x20), (byte) 0x00};
                    BluetoothLeService.getInstance().writeRXCharacteristic(value);

                    byte[] buffer = new byte[(int) txValue[2]];
                    byte[] bufferData = new byte[0];
                    if (data != null) {
                        bufferData = data;
                    }
                    data = new byte[bufferData.length + buffer.length];
                    for (int i = 0; i < buffer.length; i++) {
                        buffer[i] = txValue[3 + i];
                    }
                    System.arraycopy(bufferData, 0, data, 0, bufferData.length);
                    System.arraycopy(buffer, 0, data, bufferData.length, buffer.length);
                    byte end = (byte) (txValue[1] & 0x40);
                    if (end == (byte) 0x40) {
                        Message msg = Message.obtain();
                        msg.what = READ_RESULT;
                        msg.obj = data;
                        BluetoothControlUtil.getInstance().getmHandler().sendMessage(msg);
                        data = null;
                    }
                }
            }
        }
    };

    private byte[] data;

    public interface OnSendResultListener {
        void result(boolean result, boolean end);
    }

    private OnSendResultListener mOnSendResultListener;

    public void setOnSendResultListener(OnSendResultListener onSendResultListener) {
        this.mOnSendResultListener = onSendResultListener;
    }

    public void unregisterLocalBroadcast(Context context) {
        LocalBroadcastManager.getInstance(context).unregisterReceiver(localBroadcastReceiver);
    }

}
